ZF.add('io', function(Z) {

    var B = Z.Browser,
        F = Z.Function,
        S = Z.String,
        I = Z.namespace('IO'),

        POST = 'post',
        GET = 'get',
        COMPLETE = 'complete',
        CONTENT_TYPE = 'Content-type',
        FIRE_EVENT = 'fireEvent',
        ON_READY_STATE_CHANGE = 'onreadystatechange',
        ON_LOAD_START = 'onloadstart',
        ON_PROGRESS = 'onprogress',
        
        //progressSupport = ('onprogress' in new B.Request),
        
        defaults = {

            //evalScripts : false,
            
            //evalResponse : false,

            url : '',
            
            data : '',

            charset : 'utf-8',

            method : POST,
            
            async : true,
            
            headers : {
                'X-Requested-With' : 'XMLHttpRequest',
			    'Accept' : 'text/javascript, text/html, application/xml, text/xml, */*'
            }
        };

    var R = I.Request = Z.create({

        init : function(options) {
            var self = this;

            self.xhr = new B.Request();

            self.setOptions(options, defaults);

            self.headers = self.options.headers;
            
            return self;
        },
        
        send : function() {
            var self = this, ops = self.options, xhr = self.xhr, url = ops.url, method = ops.method, data = ops.data;

            self.running = true;

            ops.isSuccess = ops.isSuccess || self.isSuccess;

            if (method == POST) {
                self.headers[CONTENT_TYPE] = 'application/x-www-form-urlencoded; charset=' + ops.charset;
            } else {
                url += (S.contains(url, '?') ? '&' : '?') + data;
                data = null;
            }

            /*精简
            if (progressSupport){
                xhr[ON_LOAD_START] = F.bind(self.loadstart, self);
                xhr[ON_PROGRESS] = F.bind(self.progress, self);
            }
            */

            xhr.open(method.toUpperCase(), url, ops.async);
            
            xhr[ON_READY_STATE_CHANGE] = F.bind(self.onStateChange, self);

            Z.each(self.headers, function(header, key) {
                try {
                    xhr.setRequestHeader(key, header);
                } catch(e) {
                    self[FIRE_EVENT]('exception', [key, header]);
                }
            });

            self[FIRE_EVENT]('request');

            xhr.send(data);

            return self;
        },
        
        cancel : function() {

        },
        
        isSuccess : function() {
            var status = this.status;
		    return (status >= 200 && status < 300);
        },
        
        success : function(text, xml) {
            this.onSuccess(this.processScripts(text), xml);
        },
        
        failure : function() {
            this.onFailure();
        },
        
        /*精简
        loadstart : function(event) {
            this[FIRE_EVENT]('loadstart', [event, this.xhr]);
        },
        
        progress : function(event) {
            this[FIRE_EVENT]('progress', [event, this.xhr]);
        },
        */

        //processScripts : function(text) {
        //    var self = this, ops = self.options;
        //    if (ops.evalResponse || (/(ecma|java)script/).test(self.xhr.getResponseHeader('Content-type'))) {
        //        return B.exec(text);
        //    }
        //    return S.stripScripts(text, ops.evalScripts);
        //},

        processScripts : function(text) {
            return S.stripScripts(text, this.options.evalScripts);
        },
        
        //timeout : function() {
        //    this[FIRE_EVENT]('timeout', this.xhr);
        //},
        
        onSuccess : function() {
            (this[FIRE_EVENT](COMPLETE, arguments))[FIRE_EVENT]('success', arguments);
        },

        onFailure : function() {
            (this[FIRE_EVENT](COMPLETE))[FIRE_EVENT]('failure', this.xhr);
        },
        
        onStateChange : function() {
            var self = this, xhr = self.xhr;
            
            if (xhr.readyState != 4 || !self.running) {
                return;
            }

            self.running = false;

            self.status = 0;

            try {
                var status = xhr.status;
                self.status = (status == 1223) ? 204 : status;
            } catch(e) {}
            
            xhr[ON_READY_STATE_CHANGE] = Z.emptyFn;
            
            /*
            if (progressSupport) {
                xhr[ON_PROGRESS] = xhr[ON_LOAD_START] = Z.emptyFn;
            }
            */
            
            //clearTimeout(self.timer);
            
            self.response = { text : xhr.responseText || '', xml : xhr.responseXML };

            if (self.options.isSuccess.call(self, self.status)) {
                self.success(self.response.text, self.response.xml);
            } else {
                self.failure();
            }
        }

    });

    Z.extend(R.prototype, Z.Options, Z.Events);

});